package com.jianguo.web.controller.api;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jianguo.common.core.controller.BaseController;
import com.jianguo.common.core.domain.AjaxResult;
import com.jianguo.companion.domain.PzCompanion;
import com.jianguo.companion.service.IPzCompanionService;
import com.jianguo.order.domain.*;
import com.jianguo.order.service.*;
import com.jianguo.service.domain.PzServiceStep;
import com.jianguo.service.service.IPzServiceStepService;
import com.jianguo.user.domain.*;
import com.jianguo.user.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author hxq
 * @date 2024/03/15
 */
@RestController
@RequestMapping("/api/order")
public class OrderApi extends BaseController {

    @Autowired
    private IPzUserPatientService patientService;
    @Autowired
    private IPzOrderService pzOrderService;
    @Autowired
    private IPzOrderDetailService orderDetailService;
    @Autowired
    private IPzUserService pzUserService;
    @Autowired
    private IPzUserAddressService pzAddressService;
    @Autowired
    private IPzCompanionService pzCompanionService;
    @Autowired
    private IPzOrderStepRecordService orderStepRecordService;
    @Autowired
    private IPzServiceStepService serviceStepService;
    @Autowired
    private IPzBalanceService balanceService;
    @Autowired
    private IPzOrderRefundService orderRefundService;
    @Autowired
    private IPzMoneyService moneyService;
    @Autowired
    private IPzGroupService pzGroupService;
    @Autowired
    private IPzGroupMenberService groupMenberService;
    @Autowired
    private IPzGroupMsgService groupMsgService;;
    @Autowired
    private IPzRelationService relationService;
    @Autowired
    private IPzUserPatientRelationService userPatientRelationService;
    /**
     * 获取订单详细信息
     * @param id
     * @return
     */
    @GetMapping(value = "/orderInfo")
    public AjaxResult getorderInfo(String id){
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>()
                .eq(PzOrder::getId, id);

        List<PzOrder> list = pzOrderService.list(queryWrapper);


        return success(list);
    }

    /**
     * 订单详细信息
     * @param orderNumber
     * @return
     */
    @GetMapping(value = "/orderDetail")
    public AjaxResult getOrderInfo(String orderNumber){
        if (ObjectUtil.isEmpty(orderNumber)){
            return AjaxResult.error();
        }
        // 根据订单编号获取订单
        PzOrder order = pzOrderService.getOne(new LambdaQueryWrapper<PzOrder>()
                .eq(PzOrder::getOrderNumber, orderNumber));
        // 根据订单id获取订单详情
        PzOrderDetail orderDetail = orderDetailService.getOne(new LambdaQueryWrapper<PzOrderDetail>()
                .eq(PzOrderDetail::getOrderId, order.getId()));
        // 根据id获取地址
        PzUserAddress address = pzAddressService.getById(order.getAddressId());
        // 根据id获取患者
        PzUserPatient patient = patientService.getById(order.getPatientId());

        PzOrderRefund orderRefund = orderRefundService.getOne(new LambdaQueryWrapper<PzOrderRefund>()
                .eq(PzOrderRefund::getOrderId, order.getId()));
        // 设置参数
        OrderInfo orderInfo = new OrderInfo().setOrder(order).setOrderDetail(orderDetail)
                .setPatient(patient).setAddress(address).setOrderRefund(orderRefund);
        return AjaxResult.success(orderInfo);
    }

    /**
     * 获取所有订单
     * @param status
     * @return
     */
    @GetMapping(value = "/orderList")
    public AjaxResult getorderList(Integer status){
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>();

        if (status != null){
            queryWrapper.eq(PzOrder::getStatus, status);
        }

        return success(getorderList(queryWrapper));
    }
    //根据地区查找订单
    @GetMapping(value = "/orderIndex")
    public AjaxResult getorderIndex(Integer index){
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>();
        if (index == 0){
            queryWrapper.like(PzOrder::getAddress, "泉州");
        }
        if (index == 1){
            queryWrapper.like(PzOrder::getAddress, "厦门");
        }
        if (index == 2){
            queryWrapper.like(PzOrder::getAddress, "漳州");
        }
        if (index == 3){
            queryWrapper.like(PzOrder::getAddress, "福州");
        }
        return success(getorderList(queryWrapper));
    }
    // xjj写的，业务需求，避免与hxq混乱，故而另写一方法getorderList2
    @GetMapping(value = "/orderList2")
    public AjaxResult getorderList2(Integer status, HttpServletRequest request){
        String account = request.getHeader("account");
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>();
        if (ObjectUtil.isNotEmpty(account)){
            // 根据账号找到user
            PzUser pzUser = pzUserService.getOne(new LambdaQueryWrapper<PzUser>()
                    .eq(PzUser::getAccount, account));
            queryWrapper.eq(PzOrder::getUserId, pzUser.getId());
        }else {
            queryWrapper.eq(PzOrder::getUserId, 0);
        }
        if (status != null){
            queryWrapper.eq(PzOrder::getStatus, status);
            if (2 == status){
                queryWrapper.or().eq(PzOrder::getStatus, 0);
            }
        }

        return success(getorderList(queryWrapper));
    }
    //接单更改订单状态
    @GetMapping(value = "/changeStatus")
    public AjaxResult changeStatus(String orderId){
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>()
                .eq(PzOrder::getId, orderId);
        PzOrder order = pzOrderService.getOne(queryWrapper);
        order.setStatus(2L);
        order.setCompanionId("2");
        Date time = new Date();
        order.setUpdateTime(time);
        // xjj写的，接单后新建群组
        createGroup(order);
        return success(pzOrderService.updateById(order));
    }


    // 开始服务修改状态
    @GetMapping(value = "/changeStatus1")
    public AjaxResult changeStatus1(String orderId){
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>()
                .eq(PzOrder::getId, orderId);
        PzOrder order = pzOrderService.getOne(queryWrapper);
        order.setStatus(3L);
        Date time = new Date();
        order.setUpdateTime(time);
        // xjj写的，开始服务后往进度表加数据
        startStep(order);
        return success(pzOrderService.updateById(order));
    }

    // 服务完成修改状态
    @GetMapping(value = "/changeStatus2")
    public AjaxResult changeStatus2(String orderId){
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>()
                .eq(PzOrder::getId, orderId);
        PzOrder order = pzOrderService.getOne(queryWrapper);
        order.setStatus(4L);
        Date time = new Date();
        order.setUpdateTime(time);
        return success(pzOrderService.updateById(order));
    }

    /**
     * 下单
     * @param orderParam
     * @return
     */
    @PostMapping()
    public AjaxResult add(@RequestBody OrderParam orderParam)
    {
        // 根据账号找到user
        PzUser pzUser = pzUserService.getOne(new LambdaQueryWrapper<PzUser>()
                .eq(PzUser::getAccount, orderParam.getUserId()));
        orderParam.setUserId(pzUser.getId());
        return AjaxResult.success(addOrder(orderParam, 1L));
    }

    /**
     * 修改订单
     * @param orderParam
     * @return
     */
    @PostMapping("/updateOrderParam")
    public AjaxResult updateOrderParam(@RequestBody OrderParam orderParam)
    {
        pzOrderService.removeById(orderParam.getOrderId());
        orderDetailService.removeById(orderParam.getOrderDetailId());
        return AjaxResult.success(addOrder(orderParam, 2L));
    }
    @GetMapping("/getOrderParam")
    public AjaxResult getOrderParam(String id)
    {
        PzOrder order = pzOrderService.getById(id);
        PzOrderDetail orderDetail = orderDetailService.getOne(new LambdaQueryWrapper<PzOrderDetail>()
                .eq(PzOrderDetail::getOrderId, id));

        OrderParam orderParam = BeanUtil.copyProperties(orderDetail, OrderParam.class);
        orderParam.setAddressId(order.getAddressId()).setOrderId(id).setOrderDetailId(orderDetail.getId());

        PzUserAddress address = pzAddressService.getById(order.getAddressId());
        PzUserPatient patient = patientService.getById(order.getPatientId());

        EditOrderResult editOrderResult = new EditOrderResult().setOrderParam(orderParam).setPatient(patient).setAddress(address);

        return AjaxResult.success(editOrderResult);
    }

    /**
     * 订单号生成
     * @return
     */
    private static String generateOrderNumber() {
        // 获取当前时间戳作为订单编号的一部分
        long timestamp = System.currentTimeMillis();
        // 使用UUID生成随机唯一字符串作为订单编号的另一部分
        String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8);
        // 将时间戳和随机字符串组合起来作为订单编号
        String orderNumber = String.valueOf(timestamp) + uuid;
        return orderNumber;
    }
    //获取总订单数
    @GetMapping(value = "/getOrderCountById")
    public AjaxResult getOrderCountById(String id){

            // 查询订单表中陪诊员id为指定id的数据数量
            LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>()
                    .eq(PzOrder::getCompanionId, id);
            Long count = pzOrderService.count(queryWrapper);
            return success(count);
    }
    //获取收入
    @GetMapping(value = "/orderIncome")
    public AjaxResult getOrderIncome(Integer status){


        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>()
                .eq(PzOrder::getStatus, status);
        List<PzOrder> orders = pzOrderService.list(queryWrapper); // 获取符合条件的订单列表

        long totalAmount = 0L;
        for (PzOrder order : orders) {
            totalAmount += order.getAmount(); // 对订单金额进行求和
        }

        return success(totalAmount);
    }

    /**
     * 取消订单
     * @param id
     * @return
     */
    @GetMapping("/cancel")
    public AjaxResult cancelOrder(String id, String content)
    {
        PzOrder pzOrder = pzOrderService.getById(id);
        if (ObjectUtil.isEmpty(pzOrder)){
            return AjaxResult.error("订单为空");
        }
        Long status = pzOrder.getStatus();
        String userId = pzOrder.getUserId();
        PzOrderRefund.PzOrderRefundBuilder orderRefund = PzOrderRefund.builder();
        if (status == 0 || status == 1){
            orderRefund.status(1L);
            // 订单待支付和待接单状态时，可以随时取消
            pzOrder.setStatus(5L);
            pzOrderService.updateById(pzOrder);
            PzBalance balance = balanceService.getOne(new LambdaQueryWrapper<PzBalance>()
                    .eq(PzBalance::getUserid, userId));
            // 退款操作
            balance.setBalance(balance.getBalance() + pzOrder.getAmount());
            // 记录资金详情
            moneyService.save(PzMoney.builder().userid(userId).money(pzOrder.getAmount())
                    .notes("退款:"+ pzOrder.getOrderNumber()).transactionType("1").build());
            balanceService.updateById(balance);
        }else {
            orderRefund.status(0L);
        }
        // todo 这里应该写保存到退款申请表，退款由陪诊员协商

        PzOrderRefund refund = orderRefund.orderId(pzOrder.getId()).userid(userId).content(content).build();
        orderRefundService.save(refund);
        return AjaxResult.success();
    }
    /**
     * 删除订单
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public AjaxResult delete(@PathVariable String id)
    {
        return AjaxResult.success(pzOrderService.removeById(id));
    }

    private String addOrder(OrderParam orderParam, Long status){
        // 找地址
        PzUserAddress address = pzAddressService.getById(orderParam.getAddressId());
        // 找患者
        PzUserPatient patient = patientService.getById(orderParam.getPatientId());

        PzOrderDetail orderDetail = BeanUtil.copyProperties(orderParam, PzOrderDetail.class);
        PzOrder pzOrder = BeanUtil.copyProperties(orderParam, PzOrder.class);
        // 补齐参数
        pzOrder.setUsername(patient.getName()).setOrderNumber(generateOrderNumber())
                .setStatus(status).setAddress(address.getProvince()).setRemark(orderDetail.getServiceTitle());
        // 保存订单
        if (pzOrderService.save(pzOrder)){
            orderDetail.setOrderId(pzOrder.getId()).setAddress(address.getProvince())
                    .setStatus(status);
        }
        orderDetailService.save(orderDetail);
        return pzOrder.getOrderNumber();
    }


    private List<PzOrder> getorderList(LambdaQueryWrapper<PzOrder> queryWrapper){
        List<PzOrder> list = pzOrderService.list(queryWrapper);

        for (PzOrder order:list) {
            // 未支付
            if (1L == order.getStatus()){
                Date createTime = order.getCreateTime();
                DateTime date = DateUtil.date();
                long l = date.getTime() - createTime.getTime();
                // 求出订单创建已过去多久，超过10分钟的改状态
                if (l <= 600000){
                    order.setPayMethod(String.valueOf(createTime.getTime() + 600000 - date.getTime()));
                }else {
                    order.setStatus(5L);
                    pzOrderService.updateById(order);
                }
            }
        }
        return list;
    }

    private void startStep(PzOrder order){
        String orderId = order.getId();
        PzOrderDetail orderDetail = orderDetailService.getOne(new LambdaQueryWrapper<PzOrderDetail>()
                .eq(PzOrderDetail::getOrderId, orderId));
        String serviceId = orderDetail.getServiceId();
        // 根据serviceId查找服务步骤
        List<PzServiceStep> stepList = serviceStepService.list(new LambdaQueryWrapper<PzServiceStep>()
                .eq(PzServiceStep::getServiceId, serviceId));

        List<PzOrderStepRecord> orderStepRecords = new ArrayList<>();
        for (PzServiceStep step:stepList) {
            PzOrderStepRecord stepRecord = PzOrderStepRecord.builder().orderId(orderId).name(step.getName()).sort(step.getSort()).status(0L).build();
            // 如果是第一个，则设置为1完成
            if (step.getSort()  == 1L){
                stepRecord.setStatus(1L);
                stepRecord.setDoTime(order.getUpdateTime());
            }
            orderStepRecords.add(stepRecord);
        }
        // 批量保存
        orderStepRecordService.saveBatch(orderStepRecords);
    }
    //添加医嘱
    @GetMapping("/addRemark")
    public AjaxResult addReamrk(String id,String remark) {
        // 根据id找到订单
        LambdaQueryWrapper<PzOrder> queryWrapper = new LambdaQueryWrapper<PzOrder>()
                .eq(PzOrder::getId, id);
        PzOrder order = pzOrderService.getOne(queryWrapper);
        order.setRemark(remark);
        pzOrderService.saveOrUpdate(order);
        return success();
    }

    private void createGroup(PzOrder order){
        String patientId = order.getPatientId();
        LambdaQueryWrapper<PzUserPatient> queryWrapper = new LambdaQueryWrapper<PzUserPatient>().eq(PzUserPatient::getId, patientId);
        PzUserPatient patient = patientService.getOne(queryWrapper);
        PzGroup group = new PzGroup();
        group.setOrderId(order.getId()).setName(patient.getName() + "的陪诊群");
        pzGroupService.save(group);
        // 往群组成员表中添加陪诊员
        PzGroupMenber menber = new PzGroupMenber();
        // 根据陪诊员id找到陪诊员信息
        PzCompanion companion = pzCompanionService.getById(order.getCompanionId());
        menber.setGroupId(group.getId()).setUserId(order.getCompanionId()).setUserType(1L)
                .setNickname(companion.getUsername()).setPic(companion.getPicImgeRul());
        groupMenberService.save(menber);
        // 根据下单者id找到下单者信息
        PzUser user = pzUserService.getById(order.getUserId());
        PzGroupMenber menber2 = new PzGroupMenber();
        // 往群组成员表中下单者
        menber2.setUserId(order.getUserId()).setUserType(2L).setNickname(order.getUsername())
                .setPic(user.getPic()).setGroupId(group.getId());
        groupMenberService.save(menber2);
        // 根据下单者找到关系
        List<PzUserPatientRelation> relationList = userPatientRelationService.list(new LambdaQueryWrapper<PzUserPatientRelation>()
                .eq(PzUserPatientRelation::getUserId, order.getUserId())
                .eq(PzUserPatientRelation::getPatientId, patientId));

        for (PzUserPatientRelation relation:relationList) {
            // 往群组成员表中添加成员
            PzGroupMenber menber1 = new PzGroupMenber();
            menber1.setGroupId(group.getId()).setUserId(relation.getRelationId()).setUserType(2L)
                    .setNickname(relation.getNickname()).setPic(relation.getPic());
            groupMenberService.save(menber1);
        }
    }
    /**
     * 订单详细信息
     * @param orderNumber
     * @return
     */
    @GetMapping(value = "/orderDetail1")
    public AjaxResult getOrderInfo1(String orderNumber){
        if (ObjectUtil.isEmpty(orderNumber)){
            return AjaxResult.error();
        }
        // 根据订单编号获取订单
        PzOrder order = pzOrderService.getById(orderNumber);
        // 根据订单id获取订单详情
        PzOrderDetail orderDetail = orderDetailService.getOne(new LambdaQueryWrapper<PzOrderDetail>()
                .eq(PzOrderDetail::getOrderId, order.getId()));
        // 根据id获取地址
        PzUserAddress address = pzAddressService.getById(order.getAddressId());
        // 根据id获取患者
        PzUserPatient patient = patientService.getById(order.getPatientId());

        PzOrderRefund orderRefund = orderRefundService.getOne(new LambdaQueryWrapper<PzOrderRefund>()
                .eq(PzOrderRefund::getOrderId, order.getId()));
        // 设置参数
        OrderInfo orderInfo = new OrderInfo().setOrder(order).setOrderDetail(orderDetail)
                .setPatient(patient).setAddress(address).setOrderRefund(orderRefund);
        return AjaxResult.success(orderInfo);
    }
}
